// #include <stdio.h>
// #include <unistd.h>

// int main()
// {
//     while (1)
//     {
//         printf("hello linux!\n");
//     }
//     return 0;
// }

// int cnt = 0;
// while(cnt<10)
// {
//     sleep(2);
//     //scanf("%d", &cnt);
//     printf("hello world, cnt : %d\n", cnt++);
// }

// return 0;

// #include <stdio.h>
// #include <stdlib.h>
// #include <unistd.h>
// #include <sys/types.h>

// int main()
// {
//     pid_t id = fork();
//     if (id < 0)
//     {
//         perror("fork");
//         return 1;
//     }
//     else if (id > 0)
//     { // parent
//         printf("parent[%d] is sleeping...\n", getpid());
//         sleep(30);
//     }
//     else
//     {
//         printf("child[%d] is begin Z...\n", getpid());
//         sleep(5);
//         exit(EXIT_SUCCESS);
//     }
//     return 0;
// }

// 进程的退出状态必须被维持下去，因为他要告诉关心它的进程（父进程），你交给我的任务，我办的怎
// 么样了。可父进程如果一直不读取，那子进程就一直处于Z状态？是的！
// 维护退出状态本身就是要用数据维护，也属于进程基本信息，所以保存在task_struct(PCB)中，换句话
// 说，Z状态一直不退出，PCB一直都要维护？是的！
// 那一个父进程创建了很多子进程，就是不回收，是不是就会造成内存资源的浪费？是的！因为数据结构
// 对象本身就要占用内存，想想C中定义一个结构体变量（对象），是要在内存的某个位置进行开辟空
// 间

// 父进程如果提前退出，那么子进程后退出，进入Z之后，那该如何处理呢？
// 父进程先退出，子进程就称之为“孤儿进程”
// 孤儿进程被1号init进程领养，当然要有init进程回收喽。

// #include <stdio.h>
// #include <unistd.h>
// #include <stdlib.h>
// #include <unistd.h>
// #include <sys/types.h>

// int main()
// {
//     pid_t id = fork();
//     if (id < 0)
//     {
//         perror("fork");
//         return 1;
//     }
//     else if (id == 0)
//     { // child
//         printf("I am child, pid : %d\n", getpid());
//         sleep(30);
//     }
//     else
//     { // parent
//         printf("I am parent, pid: %d\n", getpid());
//         sleep(10);
//         exit(0);
//     }
//     return 0;
// }

// #include <stdio.h>
// #include <unistd.h>
// #include <sys/types.h>

// int main()
// {
//     while(1)
//     {
//         printf("hello linux!\n");
//         printf("code 的pid为 %d\n", getpid());
//     }
//     return 0;
// }

// #include <stdio.h>
// int main(int argc, char *argv[], char *env[])
// {
//     int i = 0;
//     for (; env[i]; i++)
//     {
//         printf("%s\n", env[i]);
//     }
//     return 0;
// }

// argc：表示命令行参数的个数（包括程序名本身）。
// argv：是一个指向字符指针的数组，每个元素都是一个命令行参数的字符串。
// env：指向环境变量的字符串数组，env是程序的环境变量（这是一个可选的参数，通常在标准的C环境中没有提供，具体取决于编译器和运行环境）。

// #include <stdio.h>
// int main(int argc, char *argv[])
// {
//     extern char **environ;
//     int i = 0;
//     for (; environ[i]; i++)
//     {
//         printf("%s\n", environ[i]);
//     }
//     return 0;
// }

// #include <stdio.h>
// #include <stdlib.h>
// int main()
// {
//     printf("%s\n", getenv("PATH"));
//     return 0;
// }

// #include <stdio.h>
// #include <stdlib.h>
// int main()
// {
//     char *env = getenv("MYENV");
//     if (env)
//     {
//         printf("%s\n", env);
//     }
//     return 0;
// }



// 时间片到期：在时间共享系统中，操作系统为每个进程分配一定的时间片。当时间片用完时，操作系统会中断当前进程，切换到另一个进程。
// I/O 操作：当进程等待输入/输出（I/O）操作完成时，操作系统会暂停该进程并调度其他进程。
// 进程优先级：高优先级的进程可能会抢占低优先级进程的执行权。
// 进程终止：当一个进程完成执行时，操作系统会调度其他进程继续执行。